home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / tsr_c.exe / MAIN.C < prev    next >
C/C++ Source or Header  |  1992-03-24  |  8KB  |  338 lines

  1. #pragma option -zAINIT          // change code segment class to 'INIT'
  2.                                 // so that it comes after the stack and
  3.                                 // it can be released when going resident.
  4.  
  5. #pragma option -zFINIT          // change far data segment class to 'INIT'
  6.                                 // for same reason.
  7.  
  8. #pragma option -zEINIT_DATA     // also force all far data to go to one
  9.                                 // segment (just for this module)
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <process.h>
  15. #include <dos.h>
  16. #include "vectors.h"
  17.  
  18. #define puts(a) jputs (a)       // cause the real puts() adds a newline dammit!
  19. #define ENDL()  {if (verbose) putchar ('\n');}
  20.  
  21. char far hex_buffer[5];         // used by hex();
  22.  
  23. char far init_title[]           = "JLink  Version 1.0 Copyright (c) 1992 by Borland International\n";
  24. char far init_resident[]        = "TSR is resident\n";
  25. char far init_unloaded[]        = "TSR is unloaded\n";
  26. char far init_v_psp[]           = "\nPSP:";
  27. char far init_is_loaded[]       = "\aERROR: JLink is already loaded, exiting...\n";
  28. char far init_not_loaded[]      = "\aERROR: JLink is not loaded, exiting...\n";
  29. char far init_e_unloading[]     = "\aERROR: could not unload because of INT-";
  30. char far init_bad_param[]       = "\aERROR: invalid parameter: ";
  31. char far init_hose_bad[]        = "\aERROR: extream hose error!\n";
  32. char far init_bad_speed[]       = "WARNING: invalid speed selected, resetting to default.\n";
  33.  
  34. char far init_help[]            =
  35.      "\nUsage: JLINK [options]\n\n"
  36.      " -?            Prints this help screen\n"
  37. //     " -Ffilename    Sets the filename to log to (default = test.dat)\n"
  38.      " -R            Removes the TSR from memory\n"
  39.      " -Sxxx         Sets the speed of updating (in 18ths sec)\n"
  40.      " -V            Verbose mode (-V- quite mode)\n";
  41.  
  42. int far verbose = 1;           // 0 = none, 1 = regular, 2 = extra strength
  43.  
  44. char far fname[81] = "TEST.DAT";
  45.  
  46. void _restorezero (void);      // from the BORLAND startup code
  47. int is_there (void);           // see's if we are loaded already
  48. void hook_em_danno (void);     // gets ready to go resident
  49. char *byte (BYTE);             // converts a byte into a hex string
  50. char *hex (WORD);              // converts an int to a string in hex
  51. void _hex (WORD);              // helper for hex()
  52. void jputs (char *s);          // my own string printing function
  53. int unload (void);             // unload's the resident TSR (if possible)
  54. void back_here (void);         // destination of the 'DOS unload' rollercoaster
  55.  
  56. int main (int argc, char *argv[])
  57. {
  58.   int x = 1;
  59.   WORD temp;
  60.  
  61.   if (argv[1][0] != ':')       // do title?
  62.     puts (init_title);
  63.   else
  64.     x = 2, verbose = 0;
  65.  
  66.   for (;x < argc; x++)
  67.   {
  68.     if (argv[x][0] == '-' || argv[x][0] == '/')
  69.     {
  70.       switch (toupper (argv[x][1]))
  71.       {
  72.         case 'H':
  73.         case '?':
  74.           puts (init_help);
  75.           return 3;
  76.  
  77.         case 'R':
  78.           if (unload ())
  79.             return 4;
  80.           else
  81.             return 5;
  82.  
  83.         case 'V':
  84.           verbose = 2;
  85.           if (argv[x][2] == '-')
  86.             verbose = 0;
  87.           break;
  88.  
  89.         case 'S':
  90.           temp = atoi (&argv[x][2]);
  91.           if (temp == 0 || temp > 255)
  92.             puts (init_bad_speed);
  93.           else
  94.           {
  95.             _8_max = temp;
  96.           }
  97.           break;
  98. /*
  99.         case 'F':
  100.           strcpy (fname, &(argv[x][2]));
  101.           break;
  102. */
  103.         default: goto bad_param;
  104.       }
  105.     }
  106.     else
  107.     {
  108.     bad_param:
  109.       puts (init_bad_param);
  110.       puts (argv[x]);
  111.       ENDL();
  112.       return 2;
  113.     }
  114.   }
  115.  
  116.   if (is_there ())
  117.   {
  118.     puts (init_is_loaded);
  119.     return 1;
  120.   }
  121.   else
  122.   {
  123.     if (verbose == 2)
  124.     {
  125.       puts (init_v_psp);
  126.       puts (hex (_psp));
  127.       ENDL();
  128.     }
  129.  
  130. /*
  131.     if ((file = fopen (fname, "wt")) == NULL)
  132.     {
  133.       perror (fname);
  134.       return 7;
  135.     }
  136. */
  137.     puts (init_resident);
  138.  
  139.     hook_em_danno ();
  140.  
  141.     keep(0, (_SS - _psp) + 1);
  142.   }
  143.   return 0;
  144. }
  145.  
  146. int is_there (void)
  147. {
  148.   _AH = MY_ID;
  149.   _AL = DETECT_CMD;
  150.   geninterrupt (0x2F);
  151.   if (_AX == 0xFFFF)
  152.     return 1;
  153.  
  154.   return 0;
  155. }
  156.  
  157. void hook_em_danno ()
  158. {
  159.   WORD s,o;
  160.  
  161.   _AH = 0x34;                    // UNDOC DOS get inDOS pointer
  162.   geninterrupt (0x21);
  163.   s = _ES;
  164.   o = _BX;
  165.  
  166.   indos = MK_FP (s,o);           // be nice to DOS so it doesn't "barf" on us.
  167.  
  168.  
  169.   old_8  = getvect (0x8);
  170.   old_2F = getvect (0x2F);
  171.   old_28 = getvect (0x28);
  172.  
  173.   setvect (0x8, new_8);
  174.   setvect (0x2F, new_2F);
  175.   setvect (0x28, new_28);
  176. }
  177.  
  178. char *hex (WORD x)
  179. {
  180.   _ES = FP_SEG (hex_buffer);
  181.   _DI = FP_OFF (hex_buffer);
  182.   _AX = x;
  183.   _hex (_AH);        // upper byte
  184.   _AX = x;
  185.   _hex (_AL);        // lower byte
  186.  
  187.   hex_buffer[4] = 0;
  188.   return hex_buffer;
  189. }
  190.  
  191. char *byte (BYTE x)
  192. {
  193.   _ES = FP_SEG (hex_buffer);
  194.   _DI = FP_OFF (hex_buffer);
  195.   _AL = x;
  196.   _hex (_AL);        // upper byte
  197.  
  198.   hex_buffer[2] = 0;
  199.   return hex_buffer;
  200. }
  201.  
  202. void _hex (WORD x)
  203. {
  204.   _AX = x;
  205.   asm {
  206.          mov ah, al
  207.          and al, 0fh
  208.          mov cl, 4
  209.          shr ah, cl
  210.                         // ah has MSD
  211.                         // al has LSD
  212.          or ax, 3030h
  213.          xchg al, ah
  214.  
  215.          cmp     ah, 39h
  216.          ja      _fix_ah
  217.   }
  218.   _fix_ah_ret:
  219.   asm {
  220.          cmp     al, 39h
  221.          ja      _fix_al
  222.  
  223.   }
  224.   write_it:
  225.   asm {
  226.          stosw
  227.          jmp hex_done
  228.   }
  229.   _fix_al:
  230.   asm {
  231.          sub     al, 30h
  232.          add     al, 'A' - 10
  233.          jmp     write_it
  234.   }
  235.   _fix_ah:
  236.   asm {
  237.          sub     ah, 30h
  238.          add     ah, 'A' - 10
  239.          jmp     _fix_ah_ret
  240.   }
  241.   hex_done:
  242.  
  243. }
  244.  
  245. void jputs (char *s)
  246. {
  247.   if (!verbose)
  248.     return;
  249.  
  250.   while (*s)
  251.   {
  252.     _AL = *s;
  253.     geninterrupt (0x29);         // DOS fast putchar
  254.     if (*s == '\n')
  255.     {
  256.       _AL = 13;
  257.       geninterrupt (0x29);
  258.     }
  259.     s++;
  260.   }
  261. }
  262.  
  263. int unload (void)
  264. {
  265.   WORD tsrpsp, code;
  266.   WORD far *p;
  267.  
  268.   if (!is_there())
  269.   {
  270.     puts (init_not_loaded);
  271.     return 1;
  272.   }
  273.  
  274.   _restorezero ();               // "buckle up, this could be a rough ride!"
  275.  
  276.   _AH = MY_ID;
  277.   _AL = UNLOAD_CMD;
  278.   geninterrupt (0x2F);           // make TSR unhook it's vects
  279.  
  280.   if (_AX != 0xFFFF)
  281.   {
  282.     code = _CX;                  // int vect that could not be unloaded
  283.     puts (init_e_unloading);
  284.     puts (byte (code));
  285.     ENDL();
  286.     _AX = 0x4C04;
  287.     geninterrupt (0x21);         // exit out quick
  288.   }
  289.  
  290.  
  291.   tsrpsp = _BX;
  292.  
  293.   p = MK_FP (tsrpsp, 0x0A);      // Location the TSR returns to when unloaded.
  294.                                  // this location in a PSP usually points
  295.                                  // back to command.com who loaded it.  We,
  296.                                  // however, are sneakier than DOS realizes and
  297.                                  // we make this location point back to us.
  298.                                  // (Well, let's rightfuly give credit to
  299.                                  // Mr. Schulman for this one)     <grin>
  300.  
  301.   p[0] = FP_OFF (back_here);
  302.   p[1] = FP_SEG (back_here);
  303.  
  304.   _AH = 0x50;                    // UNDOC DOS Set PSP segment
  305.   _BX = tsrpsp;
  306.   geninterrupt (0x21);           // make our TSR the current process
  307.  
  308.   _AX = 0x4C00;                  // terminate current (TSR) process
  309.   geninterrupt (0x21);           // "remember to keep your hands up and
  310.                                  // scream the whole way!"
  311.  
  312.   // NOTE: we should never get here, but instead end up in back_here()
  313.  
  314.   puts (init_hose_bad);         // "Toto, we're not in Kansas anymore!"
  315.   return 0;
  316. }
  317.  
  318. void _loadds back_here ()  // use _loadds since DOS has blown away our
  319.                            // DS value.
  320. {
  321.   // If we get here, then the TSR was successfully unloaded, and we should
  322.   // step out of our cock-pit and kiss the ground (or at least give thanks
  323.   // to the DOS gods.  Sacrafice a diskette or something. <double grin> )
  324.  
  325.   // and now for something completely different, we mu